import { Directive, ElementRef, Renderer2, HostListener, Input, Output, EventEmitter } from '@angular/core';
import { DragDropService, DragData } from '../drag-drop.service';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[app-droppable][dragEnterClass][dropTags]'
})
export class DropDirective {
  @Output() dropped = new EventEmitter<DragData>();
  @Input() dragEnterClass: string;
  @Input() dropTags: string[] = [];
  private data$;
  constructor(
    private elementRef: ElementRef,
    private rd: Renderer2,
    private service: DragDropService) {
    this.data$ = this.service.getDragData().take(1);
  }
  // 监听开始拖动
  @HostListener('dragenter', ['$event'])
  onDragEnter(ev: Event) {
    ev.preventDefault(); // 阻止默认事件
    ev.stopPropagation(); // 停止向外发射事件
    // 判断是否是当前元素出发的事件
    if (this.elementRef.nativeElement === ev.target) {
      this.data$.subscribe(dragData => {
        // 如果这个类型可以被接受
        if (this.dropTags.indexOf(dragData.tag) > -1) {
          // 往 this.ele 添加一个class
          this.rd.addClass(this.elementRef.nativeElement, this.dragEnterClass);
        }
      });
    }
  }

  // 监听拖动停止
  @HostListener('dragover', ['$event'])
  onDragOver(ev: Event) {
    ev.preventDefault(); // 阻止默认事件
    ev.stopPropagation(); // 停止向外发射事件
    if (this.elementRef.nativeElement === ev.target) {
      this.data$.subscribe(dragData => {
        if (this.dropTags.indexOf(dragData.tag) > -1) {
          this.rd.setProperty(ev, 'dataTransfer.effectAllowed', 'all');
          this.rd.setProperty(ev, 'dataTransfer.dropEffect', 'move');
        } else {
          this.rd.setProperty(ev, 'dataTransfer.effectAllowed', 'none');
          this.rd.setProperty(ev, 'dataTransfer.dropEffect', 'none');
        }
      });
    }
  }

  // 监听拖动停止
  @HostListener('dragleave', ['$event'])
  onDragLeave(ev: Event) {
    ev.preventDefault(); // 阻止默认事件
    ev.stopPropagation(); // 停止向外发射事件
    if (this.elementRef.nativeElement === ev.target) {
      this.data$.subscribe(dragData => {
        // 如果这个tag 存在
        if (this.dropTags.indexOf(dragData.tag) > -1) {
          // 从 this.ele 移除一个class
          this.rd.removeClass(this.elementRef.nativeElement, this.dragEnterClass);
        }
      });
    }
  }

  // 监听拖动停止
  @HostListener('drop', ['$event'])
  onDrop(ev: Event) {
    ev.preventDefault(); // 阻止默认事件
    ev.stopPropagation(); // 停止向外发射事件
    if (this.elementRef.nativeElement === ev.target) {
      this.data$.subscribe(dragData => {
        if (this.dropTags.indexOf(dragData.tag) > -1) {
          this.rd.removeClass(this.elementRef.nativeElement, this.dragEnterClass);
          this.service.clearDragData();
          this.dropped.emit(dragData);
        }
      });
    }
  }
}
